#include <iostream>
#include <vector>
#include <signal.h>
#include <unistd.h>


// #define BLOCK_SIGNAL 2
#define MAX_SIGNUM 31 // 信号范围

static std::vector<int> sigarr = {2};

static void showPengding(const sigset_t& pending)
{
    for(int signo = MAX_SIGNUM; signo >= 1; --signo)
    {
        // 测试signo是否属于信号集pending，是返回1，否则返回0
        if(sigismember(&pending, signo))
        {
            std::cout << "1";
        }
        else std::cout << "0";
    }
    std::cout << std::endl;
}
static void myhandler(int signo)
{
    std::cout << signo << "号信号已被递达" << std::endl;
}

int main()
{
    for(const auto& signo : sigarr) signal(signo, myhandler);

    // 1. 屏蔽指定信号
    sigset_t block, oblock, pengding;
    // 1.1 初始化——所有信号默认是不被阻塞的
    sigemptyset(&block);
    sigemptyset(&oblock);
    sigemptyset(&pengding);
    // 1.2 添加要屏蔽的信号
    // sigaddset(&block, BLOCK_SIGNAL);
    for(const auto& signo : sigarr) sigaddset(&block, signo);

    /*以上代码均是用户级代码，只是在用户层构建了一个用户级信号集，是在当前进程的栈帧中的数据结构与，并不影响内核，所以不影响当前进程*/

    // 1.3 屏蔽信号
    sigprocmask(SIG_SETMASK, &block, &oblock);

    // 2. 便利打印pending信号集
    int cnt = 10;
    while(true)
    {
        // 2.1 初始化
        sigemptyset(&pengding);
        // 2.2 获取pengding信号集
        sigpending(&pengding);
        // 2.3 打印pengding信号集
        showPengding(pengding);
        // 2.4 慢一点
        sleep(1);

        --cnt;
        if(cnt == 0)
        {
            // 解除屏蔽
            sigprocmask(SIG_SETMASK, &oblock, &block);// 一旦对特定信号解除屏蔽，一般os要至少立刻递达一个信号
            std::cout << "已解除对信号的屏蔽" << std::endl;
        }

    }

    return 0;
}